<template>
	<div class="sku-table" v-if="specs.length > 0">
		<table class="diy-table diy-skutable">
			<tr>
				<th v-for="(item, colIndex) in specs" :key="colIndex">
					{{ item.title }}
				</th>
				<th v-for="(item, colIndex) in columns" :style="{ width: item.type == 'number' ? '100px' : 'auto' }" :key="colIndex + specs.length + 1">
					{{ item.title }}
				</th>
			</tr>
			<tr>
				<td v-for="(item, colIndex) in specs" :key="colIndex">
					<el-select v-if="filterable" @change="resetTable" v-model="headerFilterParams[item.title]" placeholder="过滤查询" clearable>
						<el-option label="全部" value=""></el-option>
						<el-option v-for="(child, index2) in item.datas" :key="index2" :label="child.title" :value="child.title"></el-option>
					</el-select>
					<span v-else class="spec-title">
						{{ item.title }}
					</span>
				</td>
				<td v-for="(item, colIndex) in columns" :key="colIndex + specs.length + 1">
					<span v-if="item.readOnly">{{ item.title }}</span>
					<diy-uploadinput
						class="diygw-col-24"
						v-else-if="item.type == 'img'"
						@blur="
							() => {
								onBatchEdit(item.id);
							}
						"
						placeholder="批量修改"
						v-model="columnsValue[item.id]"
					/>
					<el-input-number
						:min="0"
						:precision="item.precision ? item.precision : 0"
						:step="item.precision ? 0.1 : 1"
						v-else-if="item.type == 'number'"
						v-model="columnsValue[item.id]"
						controls-position="right"
						:controls="false"
						class="sku-input-number"
						@blur="
							() => {
								onBatchEdit(item.id);
							}
						"
						@keyup.native.enter="
							() => {
								onBatchEdit(item.id);
							}
						"
						placeholder="批量修改"
					/>
					<el-input
						v-else
						class="diygw-col-24"
						v-model="columnsValue[item.id]"
						@blur="
							() => {
								onBatchEdit(item.id);
							}
						"
						@keyup.native.enter="
							() => {
								onBatchEdit(item.id);
							}
						"
						placeholder="批量修改"
					/>
				</td>
			</tr>
			<tr v-for="(row, rowIndex) in renderTableRows" :key="row.id">
				<td
					v-for="(child, colIndex) in row.columns"
					:class="[
						child.shouldSetRowSpan ? '' : 'hide',
						rowIndex === rowLastCanSpan[colIndex] ? 'col-last-rowspan' : '',
						colIndex < specs.length - 1 ? 'row-span-style' : '',
					]"
					:rowspan="child.shouldSetRowSpan ? assignRule[colIndex] : ''"
					:key="colIndex"
				>
					<span>{{ child.showValue }}</span>
				</td>
				<td v-for="(child, colIndex) in columns" :key="colIndex + columns.length + 1">
					<span v-if="child.readOnly">{{ row[child.id] }}</span>
					<diy-uploadinput
						v-else-if="child.type == 'img'"
						@change="
							(value) => {
								checkValue(value, child, row);
							}
						"
						:placeholder="child.title"
						v-model="row[child.id]"
					></diy-uploadinput>
					<el-input-number
						:min="0"
						:precision="child.precision ? child.precision : 0"
						:step="child.precision ? 0.1 : 1"
						v-else-if="child.type == 'number'"
						v-model="row[child.id]"
						controls-position="right"
						:controls="false"
						class="sku-input-number"
						@change="
							(value) => {
								checkValue(value, child, row);
							}
						"
						:placeholder="child.title"
					/>
					<el-input
						v-else
						v-model="row[child.id]"
						@change="
							(value) => {
								checkValue(value, child, row);
							}
						"
						:placeholder="child.title"
					/>
				</td>
			</tr>
		</table>
	</div>
</template>

<script setup name="DiySkutable">
import { uuid } from '@/utils';
import { ElMessageBox } from 'element-plus';
import { onMounted, ref, watch, computed } from 'vue';
import DiyUploadinput from '@/components/upload/uploadinput.vue';
import { useVModel } from '@vueuse/core';

const props = defineProps({
	modelValue: {
		type: Array,
		default: () => {
			return [];
		},
	},
	specs: {
		//规格配置
		type: Array,
		default: () => {
			return [];
		},
	},
	columns: {
		//自定义sku属性
		type: Array,
		default: () => {
			return [];
		},
	},
	filterable: {
		//是否开启sku搜索
		type: Boolean,
		default: true,
	},
});

const emit = defineEmits(['update:modelValue']);
const modeldata = useVModel(props, 'modelValue', emit);

const headerFilterParams = ref({});
const columnsValue = ref({});
const originTableRows = ref([]);
const renderTableRows = ref([]);

onMounted(() => {
	render();
});

function render() {
	originTableRows.value = createTable();
	renderTableRows.value = originTableRows.value;
	getData();
}

function _resetRowSpan(table) {
	table.forEach((row, rowIndex) => {
		row.columns.forEach((column, columnIndex) => {
			column.shouldSetRowSpan = shouldSetRowSpan(rowIndex, columnIndex);
		});
	});
}
function createTable() {
	let tableData = [];
	let details = props.modelValue;
	let theaderFilterParams = {};
	props.specs.forEach((item) => {
		theaderFilterParams[item.title] = '';
	});
	headerFilterParams.value = theaderFilterParams;
	for (let i = 0; i < skuTotal.value; i++) {
		let columns = props.specs.map((t, j) => {
			let { title, id } = getShowValue(i, j);
			return {
				shouldSetRowSpan: shouldSetRowSpan(i, j),
				showValue: title,
				valueId: id,
				columnName: t.title,
				columnId: t.id,
				precision: t.precision,
			};
		});
		//获取当前组合
		let pattern = columns
			.map((t) => t.valueId)
			.sort()
			.toString();
		//从详情中找回同一个组合的sku数据
		let rowDetails = details.find((t) => t.specIds === pattern);
		//当数据长度不为0,并新增了大的规格
		if (details.length > 0 && details.length >= i && !rowDetails && details[0].specIds.split(',').length != columns.length) {
			rowDetails = details[i];
		}
		tableData.push({
			id: uuid(),
			...createSkuPropertyFields(columns, i, rowDetails),
			columns,
		});
	}
	return tableData;
}
function createSkuPropertyFields(columns, rowIndex, row) {
	return props.columns.reduce((res, item) => {
		if (item.defaultValue) {
			// 设置默认值，可以为string或function，fuction时会传入行的索引和列的信息
			if (typeof item.defaultValue === 'string') {
				res[item.id] = item.defaultValue;
			} else if (typeof item.defaultValue === 'function') {
				res[item.id] = item.defaultValue({ columns, rowIndex });
			}
		} else if (row && row[item.id]) {
			res[item.id] = row[item.id] || '';
		} else {
			if (item.defaultValue) {
				// 设置默认值，可以为string或function，fuction时会传入行的索引和列的信息
				if (typeof item.defaultValue === 'string') {
					res[item.id] = item.defaultValue;
				} else if (typeof item.defaultValue === 'function') {
					res[item.id] = item.defaultValue({ columns, rowIndex });
				}
			} else if (columnsValue.value[item.id]) {
				res[item.id] = columnsValue.value[item.id];
			} else if (res.type == 'number') {
				res[item.id] = 0;
			} else {
				res[item.id] = '';
			}
		}
		return res;
	}, {});
}
function shouldSetRowSpan(rowIndex, colIndex) {
	return rowIndex % assignRule.value[colIndex] === 0;
}
function getShowValue(rowIndex, colIndex) {
	let datas = props.specs[colIndex].datas;
	let index;
	if (colIndex === props.specs.length - 1) {
		index = rowIndex % datas.length;
	} else {
		let step = assignRule.value[colIndex];
		index = Math.floor(rowIndex / step);
		if (index >= datas.length) {
			index = index % datas.length;
		}
	}
	return datas[index];
}

function onBatchEdit(id) {
	ElMessageBox.confirm(`确认批量修改吗?`, '提示', {
		customClass: 'diygw-messagebox',
		confirmButtonText: '确认',
		cancelButtonText: '取消',
		type: 'warning',
	})
		.then(() => {
			let value = columnsValue.value[id];
			renderTableRows.value.forEach((item) => {
				item[id] = value;
			});
			getData();
		})
		.catch(() => {});
}
function checkValue(value, columnInfo, row) {
	// let { id, pattern } = columnInfo;
	// if (pattern) {
	// 	(row || columnsValue.value)[id] = value.replace(pattern, '');
	// }
	getData();
}
function getData() {
	let data = originTableRows.value.map((t) => {
		let columnObj = props.columns.reduce((res, item) => {
			res[item.id] = item.format ? item.format(t[item.id]) : t[item.id];
			return res;
		}, {});
		return {
			specIds: t.columns.map((t) => t.valueId).join(','),
			...columnObj,
		};
	});
	modeldata.value = data;
}

const hasFilter = computed(() => {
	return Object.values(headerFilterParams.value).filter((t) => !!t).length > 0;
});

const renderSpecs = computed(() => {
	return props.specs
		.map((t) => t.datas.length)
		.map((t, index) => {
			return hasFilter.value ? (headerFilterParams.value[props.specs[index].title] ? 1 : t) : t;
		});
});

const skuTotal = computed(() => {
	return renderSpecs.value.reduce((result, item) => result * item, renderSpecs.value.length ? 1 : 0);
});

const assignRule = computed(() => {
	return renderSpecs.value.reduce((result, item, index) => {
		let preValue = result[index - 1];
		if (preValue) {
			result.push(preValue / item);
		} else {
			result.push(skuTotal.value / item);
		}
		return result;
	}, []);
});

const rowLastCanSpan = computed(() => {
	let indexArr = Array.from(new Array(skuTotal.value).keys()); //生成行的索引数组
	//每列可以合并的最后一行的行索引数组，为了设置样式
	return assignRule.value.map((t, index, array) => {
		return index === array.length - 1 ? null : indexArr.filter((row) => row % t === 0).pop();
	});
});

watch(
	() => props.specs,
	() => {
		render();
	},
	{
		deep: true,
		immediate: true,
	}
);
function resetTable() {
	if (hasFilter.value) {
		let trenderTableRows = originTableRows.value.filter((t) => {
			return t.columns.reduce((res, item) => {
				let filterValue = headerFilterParams.value[item.columnName];
				return filterValue ? res && item.showValue === filterValue : res;
			}, true);
		});
		_resetRowSpan(trenderTableRows);
		renderTableRows.value = trenderTableRows;
	} else {
		_resetRowSpan(originTableRows.value);
		renderTableRows.value = originTableRows.value;
	}
}
// watch(
// 	headerFilterParams,
// 	() => {
// 		resetTable();
// 	},
// 	{
// 		deep: true,
// 		immediate: true,
// 	}
// );
</script>
